package org.dtrd.modules.questionnaire.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.modules.questionnaire.entity.bean.QuestionnaireDataDetail;
import org.dtrd.modules.questionnaire.entity.bean.QuestionnaireDataListInfo;
import org.dtrd.modules.questionnaire.entity.bean.ScoreData;
import org.dtrd.modules.questionnaire.entity.po.DtrdEntRdQuestionnaireData;
import org.dtrd.modules.questionnaire.entity.request.QuestionnaireDataListRequest;
import org.dtrd.modules.questionnaire.entity.request.QuestionnaireDataPageRequest;
import org.dtrd.modules.questionnaire.mapper.DtrdEntRdQuestionnaireDataMapper;
import org.dtrd.modules.questionnaire.service.IDtrdEntRdQuestionnaireDataService;
import org.dtrd.modules.questionnaire.service.IDtrdEntRdQuestionnaireService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xiao
 * @since 2022-06-16
 */
@Slf4j
@DS("multi-datasource1")
@Service
public class DtrdEntRdQuestionnaireDataServiceImpl extends ServiceImpl<DtrdEntRdQuestionnaireDataMapper, DtrdEntRdQuestionnaireData> implements IDtrdEntRdQuestionnaireDataService {

    private DtrdEntRdQuestionnaireDataMapper dtrdEntRdQuestionnaireDataMapper;

    @Autowired
    private IDtrdEntRdQuestionnaireService questionnaireService;

    @Override
    public List<QuestionnaireDataListInfo> getQuestionnaireDataList(QuestionnaireDataListRequest request) {
        LambdaQueryWrapper<DtrdEntRdQuestionnaireData> queryWrapper = baseQueryWrapper();
        List<DtrdEntRdQuestionnaireData> poList = list(queryWrapper);
        List<QuestionnaireDataListInfo> dtoList = new ArrayList<>(poList.size());
        if (!poList.isEmpty()) {
            dtoList = poList.stream().map(QuestionnaireDataListInfo::new).collect(Collectors.toList());
        }
        return dtoList;
    }

    @Override
    public IPage<QuestionnaireDataListInfo> pageQuestionnaireData(QuestionnaireDataPageRequest request) {
        LambdaQueryWrapper<DtrdEntRdQuestionnaireData> queryWrapper = baseQueryWrapper();
        IPage<DtrdEntRdQuestionnaireData> page = new Page<>(request.getPageNum(), request.getPageSize());
        page = this.page(page, queryWrapper);
        return page.convert(QuestionnaireDataListInfo::new);
    }

    @Override
    public QuestionnaireDataDetail getQuestionnaireData(Integer dataId) {
        DtrdEntRdQuestionnaireData dtrdEntRdQuestionnaireData = getById(dataId);
        return Optional.ofNullable(dtrdEntRdQuestionnaireData)
                .map(po -> new QuestionnaireDataDetail().parseFromPo(po))
                .orElse(null);
    }

    @Override
    public boolean saveOrUpdateQuestionnaireData(QuestionnaireDataDetail dto) {
        DtrdEntRdQuestionnaireData dtrdEntRdQuestionnaireData = new DtrdEntRdQuestionnaireData();
        if (dto.getDataId() == null) {
            dtrdEntRdQuestionnaireData = dtrdEntRdQuestionnaireData.init();
        }
        // 先删除再添加
        LambdaQueryWrapper<DtrdEntRdQuestionnaireData> removeWrapper = Wrappers.lambdaQuery(DtrdEntRdQuestionnaireData.class)
                .eq(DtrdEntRdQuestionnaireData::getQuestionType, dto.getQuestionType())
                .eq(DtrdEntRdQuestionnaireData::getPatientId, dto.getPatientId())
                .eq(DtrdEntRdQuestionnaireData::getQuestionId, dto.getQuestionId());
        remove(removeWrapper);

        dtrdEntRdQuestionnaireData.parseFromDto(dto);
        return save(dtrdEntRdQuestionnaireData);
    }

    @Override
    public boolean removeQuestionnaireData(Integer dataId) {
        return removeById(dataId);
    }

    private LambdaQueryWrapper<DtrdEntRdQuestionnaireData> baseQueryWrapper() {
        return Wrappers.lambdaQuery(DtrdEntRdQuestionnaireData.class);
    }

    private LambdaUpdateWrapper<DtrdEntRdQuestionnaireData> baseUpdateWrapper() {
        return Wrappers.lambdaUpdate(DtrdEntRdQuestionnaireData.class);
    }

    public Integer getLastAnswerQuestionId(String type, Integer patientId) {
        LambdaQueryWrapper<DtrdEntRdQuestionnaireData> dataWrapper = Wrappers.lambdaQuery(DtrdEntRdQuestionnaireData.class)
                .eq(DtrdEntRdQuestionnaireData::getQuestionType, type)
                .eq(DtrdEntRdQuestionnaireData::getPatientId, patientId)
                .orderByDesc(DtrdEntRdQuestionnaireData::getQuestionId);
        dataWrapper.last("limit 1");
        DtrdEntRdQuestionnaireData answerLastOne = getOne(dataWrapper);

        if (answerLastOne != null) {
            return answerLastOne.getQuestionId();
        }
        else {
            return -1;
        }
    }

    @Override
    public JSONObject getPatientQuestionStatus(Integer patientId, String type) {


        Integer questionLastOneId = questionnaireService.getLastQuestion(type);

        Integer lastAnswerQuestionId = getLastAnswerQuestionId(type, patientId);
        Boolean isFinished = Objects.equals(lastAnswerQuestionId, questionLastOneId);

        JSONObject result = new JSONObject();
        result.put("is_finished", isFinished);
        result.put("current", lastAnswerQuestionId);
        if (isFinished) {
            // 生成得分记录
            JSONArray scoreData = getScoreData(patientId, type);
            result.put("data", scoreData);
        } else {
            result.put("data", null);
        }

        return result;
    }

    public JSONArray getScoreData(Integer patientId, String type) {

        //JSONObject score = new JSONObject();
        JSONArray score = new JSONArray();
        switch (type) {
            case "life_way":
                LambdaQueryWrapper<DtrdEntRdQuestionnaireData> dataWrapper = Wrappers.lambdaQuery(DtrdEntRdQuestionnaireData.class)
                        .eq(DtrdEntRdQuestionnaireData::getQuestionType, type)
                        .eq(DtrdEntRdQuestionnaireData::getPatientId, patientId);
                List<DtrdEntRdQuestionnaireData> answers =  list(dataWrapper);
                AtomicReference<Float> score1 = new AtomicReference<>((float) 0);
                AtomicReference<Float> score2 = new AtomicReference<>((float) 0);
                AtomicReference<Float> score3 = new AtomicReference<>((float) 0);
                answers.forEach(answer -> {
                    if (answer.getQuestionId() <= 12) {
                        score1.updateAndGet(v -> (float) (v + answer.getScore()));
                    } else if (answer.getQuestionId() <= 30) {
                        score2.updateAndGet(v -> (float) (v + answer.getScore()));
                    } else {
                        score3.updateAndGet(v -> (float) (v + answer.getScore()));
                    }
                });

                score.add(new ScoreData("生活方式", score1.get()));
                score.add(new ScoreData("身心健康", score2.get()));
                score.add(new ScoreData("自我健康", score3.get()));
                break;
        }


        return score;
    }
}
